// @author        GIJoe
// @license       http://creativecommons.org/licenses/by-nc-sa/3.0/

//--- to test localStorage in firefox
//delete GM_log; delete GM_getValue; delete GM_setValue; delete GM_deleteValue; delete GM_xmlhttpRequest; delete GM_openInTab; delete GM_registerMenuCommand;

var gvar = function(){}
// Global variables
function GM_ApiBrowserCheck(){
    const GMSTORAGE_PATH = 'GM_';
    // You can change it to avoid conflict with others scripts
    GM_addStyle = function(css){
        var style = document.createElement('style');
        style.textContent = css;
        document.getElementsByTagName('head')[0].appendChild(style);
    }
    if (typeof(unsafeWindow) == 'undefined'){
        unsafeWindow = window;
    }
    if (typeof(GM_log) == 'undefined'){
        GM_log = function(msg){
            try{
                unsafeWindow.console.log('GM_log: ' + msg);
            } catch(e){}
        };
    }
    GM_clog = function(msg){
        if (arguments.callee.counter){
            arguments.callee.counter++;
        } else{
            arguments.callee.counter = 1;
        }
        GM_log('(' + arguments.callee.counter + ') ' + msg);
    }
    GM_addGlobalStyle = function(css){
        // Redefine GM_addGlobalStyle with a better routine
        var sel = document.createElement('style');
        sel.setAttribute('type', 'text/css');
        sel.appendChild(document.createTextNode(css));
        var hel = document.documentElement.firstChild;
        while (hel && hel.nodeName != 'HEAD'){
            hel = hel.nextSibling;
        }
        if (hel && hel.nodeName == 'HEAD'){
            hel.appendChild(sel);
        } else{
            document.body.insertBefore(sel, document.body.firstChild);
        }
        return sel;
    }
    var needApiUpgrade = false;
    if (window.navigator.appName.match(/^opera/i) && typeof(window.opera) != 'undefined'){
        needApiUpgrade = true;
        gvar.isOpera = true;
        GM_log = window.opera.postError;
    }
    if (typeof(GM_setValue) != 'undefined'){
        var gsv; try { gsv=GM_setValue.toString(); } catch(e) { gsv='staticArgs'; }
        if (gsv.indexOf('staticArgs') > 0){
            gvar.isGreaseMonkey = true;
        }
        // test GM_hitch
        else if (gsv.match(/not\s+supported/)){
            needApiUpgrade = true;
            gvar.isBuggedChrome = true;
        }
    } else{
        needApiUpgrade = true;
    }

    if (needApiUpgrade){
        var ws = null;
        try{
            ws = typeof(unsafeWindow.localStorage);
            unsafeWindow.localStorage.length;
        } catch(e){
            ws = null;
        }
        // Catch Security error
        if (ws == 'object'){
            GM_getValue = function(name, defValue){
                var value = unsafeWindow.localStorage.getItem(GMSTORAGE_PATH + name);
                if (value == null){
                    return defValue;
                } else{
                    switch (value.substr(0, 2)){
                    case 'S]':
                        return value.substr(2);
                    case 'N]':
                        return parseInt(value.substr(2));
                    case 'B]':
                        return value.substr(2) == 'true';
                    }
                }
                return value;
            }
            GM_setValue = function(name, value){
                switch (typeof(value)){
                case 'string':
                    unsafeWindow.localStorage.setItem(GMSTORAGE_PATH + name, 'S]' + value);
                    break;
                case 'number':
                    if (value.toString().indexOf('.') < 0){
                        unsafeWindow.localStorage.setItem(GMSTORAGE_PATH + name, 'N]' + value);
                    }
                    break;
                case 'boolean':
                    unsafeWindow.localStorage.setItem(GMSTORAGE_PATH + name, 'B]' + value);
                    break;
                }
            }
            GM_deleteValue = function(name){
                unsafeWindow.localStorage.removeItem(GMSTORAGE_PATH + name);
            }
        } else if (!gvar.isOpera || typeof(GM_setValue) == 'undefined'){
            gvar.temporarilyStorage = new Array();
            GM_getValue = function(name, defValue){
                if (typeof(gvar.temporarilyStorage[GMSTORAGE_PATH + name]) == 'undefined'){
                    return defValue;
                } else{
                    return gvar.temporarilyStorage[GMSTORAGE_PATH + name];
                }
            }
            GM_setValue = function(name, value){
                switch (typeof(value)){
                case "string":
                case "boolean":
                case "number":
                    gvar.temporarilyStorage[GMSTORAGE_PATH + name] = value;
                }
            }
            GM_deleteValue = function(name){
                delete gvar.temporarilyStorage[GMSTORAGE_PATH + name];
            };
        }
        if (typeof(GM_openInTab) == 'undefined'){
            GM_openInTab = function(url){
                unsafeWindow.open(url, "");
            }
        }
        if (typeof(GM_registerMenuCommand) == 'undefined'){
            GM_registerMenuCommand = function(name, cmd){
                GM_log("Notice: GM_registerMenuCommand is not supported.");
            }
        }
        // Dummy
        if (!gvar.isOpera || typeof(GM_xmlhttpRequest) == 'undefined'){
            GM_xmlhttpRequest = function(obj){
                var request = new XMLHttpRequest();
                request.onreadystatechange = function(){
                    if (obj.onreadystatechange){
                        obj.onreadystatechange(request);
                    };
                    if (request.readyState == 4 && obj.onload){
                        obj.onload(request);
                    }
                }
                request.onerror = function(){
                    if (obj.onerror){
                        obj.onerror(request);
                    }
                }
                try{
                    request.open(obj.method, obj.url, true);
                } catch(e){
                    if (obj.onerror){
                        obj.onerror({
                            readyState: 4,
                            responseHeaders: '',
                            responseText: '',
                            responseXML: '',
                            status: 403,
                            statusText: 'Forbidden'
                        });
                    };
                    return;
                }
                if (obj.headers){
                    for (name in obj.headers){
                        request.setRequestHeader(name, obj.headers[name]);
                    }
                }
                request.send(obj.data);
                return request;
            }
        }
    }
}
GM_ApiBrowserCheck();
